/*
 *  Collin's Binary Instrumentation Tool/Framework for Android
 *  Collin Mulliner <collin[at]mulliner.org>
 *  http://www.mulliner.org/android/
 *
 *  (c) 2012,2013
 *
 *  License: LGPL v2.1
 *
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <string.h>
#include <termios.h>
#include <pthread.h>
#include <sys/epoll.h>

#include <jni.h>
#include <stdlib.h>

#include "../base/hook.h"
#include "../base/base.h"
#include "mono.h"






#undef log

#define log(...) \
        {LOGD(__VA_ARGS__);}


// this file is going to be compiled into a thumb mode binary

void __attribute__ ((constructor)) my_init(void);

static struct hook_t eph;

// for demo code only
static int counter;

// arm version of hook
extern struct MonoImage *
monohook_arm (char *data, int data_len, int need_copy, char *status, int refonly, const char *name);

/*  
 *  log function to pass to the hooking library to implement central loggin
 *
 *  see: set_logfunction() in base.h
 */
static void my_log(char *msg)
{
	log("%s", msg)
}

struct MonoImage *
monohook (char *data, int data_len, int need_copy, char *status, int refonly, const char *name)
{
	struct MonoImage * (*orig_monofunc)(char *data, int data_len, int need_copy, char *status, int refonly, const char *name);
	orig_monofunc = (void*)eph.orig;

	hook_precall(&eph);
	int res = orig_monofunc(data, data_len, need_copy, status,refonly,name);
	if (counter) {
		hook_postcall(&eph);
		LOGD("mono_image_open_from_data_with_name() called\n");
		counter--;
		if (!counter)
			log("removing hook for epoll_wait()\n");
	}
        
	return res;
}

void my_init(void)
{
	counter = 3;

	LOGD("%s started\n", __FILE__);
 
	set_logfunction(my_log);

	hook(&eph, getpid(), "libmono.", "mono_image_open_from_data_with_name", 
		monohook_arm, monohook);
}

